import {
  createRouter,
  createWebHashHistory,
  NavigationGuardNext, NavigationFailure,
  RouteLocationNormalized
} from 'vue-router'
import routes from './module/base-routes'
import routes1 from './module/base-routes1'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import { useUserStore } from "@/store/user";
import {checkMenuAuth} from '@/api/module/menu';
import {useBootStore} from "@/store/boot";
import {useSimulateStore} from "@/store/simulate";
import {kickOutByToken} from "@/api/module/user";
import {layer} from "@layui/layui-vue";

NProgress.configure({ showSpinner: false })

const router = createRouter({
  history: createWebHashHistory(),
  routes: [
      ...routes,
      ...routes1
  ]
})

/**
 * Router 前置拦截
 * 
 * 1.验证 token 存在, 并且有效, 否则 -> login.vue
 * 2.验证 permission 存在, 否则 -> 403.vue
 * 3.验证 router 是否存在, 否则 -> 404.vue
 * 
 * @param to 目标
 * @param from 来至 
 */
router.beforeEach((to: RouteLocationNormalized, from: RouteLocationNormalized, next: NavigationGuardNext) => {
  NProgress.start();

  // 排除不需要session的路由，此处为微信回调跳转的页面
  if (to.path.startsWith('/wx/')) {
    next();
    return;
  }

  const userStore = useUserStore();
  const bootStore = useBootStore();


  if(to.matched.length == 0) {
    if (bootStore.simulate) {
      next({path: '/simulate/error/404'})
      return;
    }else {
      next({path: '/error/404'})
      return;
    }
  } else {
    if (bootStore.simulate && to.path.indexOf("/simulate") < 0) {
      kickOutSimulate().then(res=>{
        if (res){
          next()
        }
        return;
      });
    }else {
      if (!userStore.token) {
        if(to.path !== '/login') {
          userStore.delAll();
          next({
            path: '/login',
            query:{back: to.path}
          });
          return;
        }else {
          next();
          return;
        }
      }
      next()
    }
  }
})

const kickOutSimulate = async ()=> {
  const bootStore = useBootStore();
  const simulateStore = useSimulateStore();
  // 初始化时，先退出模拟登陆，并删除缓存中的模拟用户信息
  const res = await kickOutByToken();
  if (res.code !== 200) {
    notify("退出模拟登陆失败");
    return false
  }
  bootStore.clearSimulate()
  simulateStore.delAll();
  location.reload()
  return true
}

const notify = (msg,type:"error") =>{
  layer.notify({
    title: type,
    content: msg,
    icon:2
  })
}

router.beforeResolve((to: RouteLocationNormalized, from: RouteLocationNormalized, next: NavigationGuardNext) => {
  // 获取菜单按钮
  const menuCode = to.meta.menuCode as string;
  if (!menuCode) {
    next();
    return;
  }
  checkMenuAuth(menuCode).then(res=>{
    if(res.code === 200) {
      next();
    }else if(res.code === 401) {
      userStore.delAll();
      next({
        path: '/login',
        query:{back: from.path}
      });
    }else if (res.code === 403) {
      if (bootStore.simulate) {
        next({path: '/simulate/error/403'})
      }else {
        next({path: '/error/403'})
      }
    }else {
      next();
    }
  }).catch(err=>{
    console.log(err)
    notify("菜单权限校验异常")
    next()
    return
  })
})

router.afterEach((to: RouteLocationNormalized, from: RouteLocationNormalized, failure?: NavigationFailure | void) => {

  NProgress.done();
})

export default router